home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-04-22 | 17.9 KB | 673 lines | [TEXT/MPS ] |
- /*
- File: PrinterGX.cpp
-
- Contains: QuickDraw GX printing support for OpenDoc printing utility
-
- Owned by: Jens Alfke (Written by Thomas Weisbach & Jens Alfke)
-
- Copyright: © 1996 by Apple Computer, Inc., all rights reserved.
-
- Change History (most recent first):
-
- <2> 2/2/96 JA Filled in header comments.
- <1> 2/2/96 JA first checked in
-
- To Do:
- */
-
-
- // -- OpenDoc --
-
- #ifndef _ALTPOINT_
- #include <AltPoint.h>
- #endif
-
- #ifndef SOM_ODCanvas_xh
- #include <Canvas.xh>
- #endif
-
- #ifndef SOM_ODClipboard_xh
- #include <Clipbd.xh>
- #endif
-
- #ifndef SOM_Module_OpenDoc_Commands_defined
- #include <CmdDefs.xh>
- #endif
-
- #ifndef SOM_ODDispatcher_xh
- #include <Disptch.xh>
- #endif
-
- #ifndef SOM_ODFacet_xh
- #include <Facet.xh>
- #endif
-
- #ifndef SOM_ODFrame_xh
- #include <Frame.xh>
- #endif
-
- #ifndef SOM_ODMenuBar_xh
- #include <MenuBar.xh>
- #endif
-
- #ifndef SOM_ODSession_xh
- #include <ODSessn.xh>
- #endif
-
- #ifndef SOM_ODStorageSystem_xh
- #include <ODStor.xh>
- #endif
-
- #ifndef SOM_ODPart_xh
- #include <Part.xh>
- #endif
-
- #ifndef SOM_ODPlatformTypeList_xh
- #include <PfTypLs.xh>
- #endif
-
- #ifndef SOM_ODShape_xh
- #include <Shape.xh>
- #endif
-
- #ifndef SOM_Module_OpenDoc_StdProps_defined
- #include <StdProps.xh>
- #endif
-
- #ifndef SOM_Module_OpenDoc_StdTypes_defined
- #include <StdTypes.xh>
- #endif
-
- #ifndef SOM_ODTransform_xh
- #include <Trnsform.xh>
- #endif
-
- #ifndef SOM_ODWindowState_xh
- #include <WinStat.xh>
- #endif
-
- // -- OpenDoc Utilities --
-
- #ifndef _EXCEPT_
- #include <Except.h>
- #endif
-
- #ifndef _ISOSTR_
- #include <ISOStr.h>
- #endif
-
- #ifndef _DLOGUTIL_
- #include <DlogUtil.h>
- #endif
-
- #ifndef _ODDEBUG_
- #include <ODDebug.h>
- #endif
-
- #ifndef _ODNEW_
- #include <ODNew.h>
- #endif
-
- #ifndef _ODUTILS_
- #include <ODUtils.h>
- #endif
-
- #ifndef _STORUTIL_
- #include <StorUtil.h>
- #endif
-
- #ifndef _TEMPOBJ_
- #include <TempObj.h>
- #endif
-
- #ifndef _USERSRCM_
- #include <UseRsrcM.h>
- #endif
-
- // -- MacToolbox --
-
- #ifndef __GXGRAPHICS__
- #include <GXGraphics.h>
- #endif
-
- #ifndef __TEXTUTILS__
- #include <TextUtils.h>
- #endif
-
- // -- Printer --
- #define _PRINTER_PRIVATE_
- #ifndef _PRINTER_
- #include "Printer.h"
- #endif
-
- #pragma segment Printer
-
-
- //---------------------------------------------------------------------------------
- // THROW_IF_JOB_ERROR [static]
- //---------------------------------------------------------------------------------
-
- static void
- THROW_IF_JOB_ERROR( gxJob job )
- {
- OSErr err= GXGetJobError(job);
- if( err ) THROW(err);
- }
-
-
- //=================================================================================
- // PrintingEventHandler declaration
- // A stack-based object that temporarily installs a GX printing event override
- // to forward some events (activate/deactivate/etc.) to the OpenDoc dispatcher.
- //=================================================================================
-
- class PrintingEventHandler :Destructo
- {
- public:
- PrintingEventHandler(Environment* ev, ODSession* session, gxJob job);
- ~PrintingEventHandler();
-
- static OSErr PrintingEventOverride(EventRecord *anEvent, Boolean filterEvent);
-
- private:
- static Environment* sEv;
- static ODSession* sSession;
- static gxJob sgxJob;
-
- gxJob fgxJob;
- GXPrintingEventUPP fPrintingEventOverrideProcPtr;
- };
-
-
- //=================================================================================
- // CGXPrinter implementation
- //=================================================================================
-
- //---------------------------------------------------------------------------------
- // CGXPrinter::CGXPrinter
- //---------------------------------------------------------------------------------
-
- CGXPrinter::CGXPrinter( )
- {
- fJob = kODNULL;
- fViewPort = kODNULL;
- fQDPort = kODNULL;
- fPrintAShapeProcPtr = kODNULL;
- fJobStarted = kODFalse;
- fPageOpen = kODFalse;
- }
-
- //---------------------------------------------------------------------------------
- // CGXPrinter::~CGXPrinter
- //---------------------------------------------------------------------------------
-
- CGXPrinter::~CGXPrinter()
- {
- if( fJob ) {
- GXDisposeJob(fJob);
- }
- if( fPrintingOpen ) {
- GXExitPrinting();
- fPrintingOpen = kODFalse;
- }
- }
-
- //---------------------------------------------------------------------------------
- // CGXPrinter::Initialize
- //---------------------------------------------------------------------------------
-
- void CGXPrinter::Initialize( Environment *ev, ODStorageUnit *su )
- {
- // We can't open and close GX printing on every operation the way we could
- // with QD. We have to leave it open for as long as we are going to use it,
- // or else objects like fJob will be invalidated. So we open it now and
- // don't close it until we get to the destructor.
-
- inherited::Initialize(ev,su);
- THROW_IF_ERROR( GXInitPrinting() );
- fPrintingOpen = kODTrue;
- }
-
- //---------------------------------------------------------------------------------
- // CGXPrinter::ReadJobFromHandle
- //---------------------------------------------------------------------------------
-
- ODPlatformPrintJob CGXPrinter::ReadJobFromHandle(ODValueType valueType, ODHandle h)
- {
- // We can either read a streamed-out GX job or convert an old-style THPrint.
-
- if( ODISOStrEqual(valueType,kODTypeGXPageSetup) ) {
- fJob = GXUnflattenJobFromHdl(kODNULL, (Handle)h);
-
- } else if( ODISOStrEqual(valueType,kODTypeQuickDrawPageSetup) ) {
- if( GXNewJob(&fJob) == noErr )
- GXConvertPrintRecord(fJob, (THPrint)h);
-
- } else
- WARN("Unknown value type");
-
- ODDisposeHandle(h);
- if( fJob && GXGetJobError(fJob) ) {
- WARN("Error %d reading GX job",GXGetJobError(fJob));
- if( fJob ) GXDisposeJob(fJob);
- fJob = kODNULL;
- }
-
- return (ODPlatformPrintJob)fJob;
- }
-
- //---------------------------------------------------------------------------------
- // CGXPrinter::CreateNewJob
- //---------------------------------------------------------------------------------
-
- ODPlatformPrintJob CGXPrinter::CreateNewJob()
- {
- // Throw an exception if we can't create a print job, since we will certainly
- // not be able to continue!
-
- THROW_IF_ERROR( GXNewJob(&fJob) );
- return (ODPlatformPrintJob) fJob;
- }
-
- //---------------------------------------------------------------------------------
- // CGXPrinter::CopyJobToHandle
- //---------------------------------------------------------------------------------
-
- ODHandle CGXPrinter::CopyJobToHandle( )
- {
- ODHandle jobHandle = ODNewHandle(0);
- GXFlattenJobToHdl(fJob, (Handle)jobHandle);
- if( GXGetJobError(fJob) ) {
- ODDisposeHandle(jobHandle);
- THROW_IF_ERROR(GXGetJobError(fJob));
- }
- return jobHandle;
- }
-
- //---------------------------------------------------------------------------------
- // CGXPrinter::GetPageRect
- //---------------------------------------------------------------------------------
-
- ODRect CGXPrinter::GetPageRect( Environment *ev )
- {
- // Doesn't handle custom page formats; assumes all pages have same bbox.
-
- ODRect pageRect;
-
- this->GetPlatformPrintJob(ev); // Force internalization of fJob
-
- gxFormat pageFormat = GXGetJobFormat(fJob, 1);
- GXGetFormatDimensions(pageFormat, (gxRectangle*) &pageRect, kODNULL);
-
- return pageRect;
- }
-
- //---------------------------------------------------------------------------------
- // CGXPrinter::CreatePrintingPlatformCanvas
- //---------------------------------------------------------------------------------
-
- ODPlatformCanvas
- CGXPrinter::CreatePrintingPlatformCanvas( Environment* ev, ODGraphicsSystem g,
- ODFrame *initiator, ODShape *area )
- {
- switch( g ) {
- case kODQuickDrawGX: {
- // Start print job & create printing viewport.
- long firstPage, lastPage;
- GXGetJobPageRange(fJob, &firstPage, &lastPage);
- ODUShort pageCount = this->CountPages(ev, area);
- if ( lastPage > pageCount )
- lastPage = pageCount;
-
- Str255 windowTitle;
- {
- TempODWindow w = fSession->GetWindowState(ev)->AcquireFrontRootWindow(ev);
- GetWTitle( w->GetPlatformWindow(ev), windowTitle );
- }
-
- GXStartJob(fJob, windowTitle, lastPage - firstPage + 1);
- THROW_IF_ERROR(GXGetJobError(fJob));
- fJobStarted = kODTrue;
-
- WASSERT(fViewPort==kODNULL);
- fViewPort = GXNewViewPort(gxScreenViewDevices);
- return (ODPlatformCanvas) fViewPort;
- // The viewport isn't hooked up to the job yet,
- // but it will be in OpenPage.
- }
-
- case kODQuickDraw: {
- // Find the frame's window's port:
- TempODWindow window = initiator->AcquireWindow(ev);
- fQDPort = window->GetPlatformWindow(ev);
-
- fPrintAShapeProcPtr = NewgxShapeSpoolProc(CGXPrinter::PrintAShape);
-
- return (ODPlatformCanvas) fQDPort;
- }
-
- default: {
- THROW(kODErrInvalidGraphicsSystem);
- return kODNULL;
- }
- }
- }
-
- //---------------------------------------------------------------------------------
- // CGXPrinter::OpenPage
- //---------------------------------------------------------------------------------
-
- void CGXPrinter::OpenPage( Environment*, ODUShort page )
- {
- // Get the specific page format. (note: we don't support
- // custom page setup, yet, so we always get the first page's
- // format).
-
- gxFormat pageFormat = GXGetJobFormat(fJob, 1);
-
- GXStartPage(fJob, page, pageFormat, 1, &fViewPort);
-
- THROW_IF_JOB_ERROR(fJob);
-
- fPageOpen = kODTrue;
-
- // Now install the QD->GX translator:
- Point patStretch = {1, 1};
- Rect everywhereRect = {0,0,32767,32767};
-
- GXInstallQDTranslator(fQDPort,
- gxDefaultOptionsTranslation,
- &everywhereRect, &everywhereRect,
- patStretch,
- fPrintAShapeProcPtr,
- this);
- }
-
- //---------------------------------------------------------------------------------
- // CGXPrinter::ClosePage
- //---------------------------------------------------------------------------------
-
- void
- CGXPrinter::ClosePage( Environment* )
- {
- if( fPageOpen ) {
- // Finish the page.
- if( fQDPort )
- GXRemoveQDTranslator(fQDPort, kODNULL);
-
- GXFinishPage(fJob);
-
- fPageOpen = kODFalse;
-
- THROW_IF_JOB_ERROR(fJob);
- }
- }
-
- //---------------------------------------------------------------------------------
- // CGXPrinter::CleanupPrintingEnv
- //---------------------------------------------------------------------------------
-
- void CGXPrinter::CleanupPrintingEnv(Environment* ev, ODFrame* initiator)
- {
- // This routine should not throw exeptions and must call the inherited method.
-
- if( fJobStarted ) {
- fJobStarted = kODFalse;
- GXFinishJob(fJob);
- if( GXGetJobError(fJob) )
- WARN("Error %d finishing job",GXGetJobError(fJob));
- }
-
- if( fPrintAShapeProcPtr ) {
- DisposeRoutineDescriptor(fPrintAShapeProcPtr);
- fPrintAShapeProcPtr = kODNULL;
- }
-
- if( fViewPort ) {
- GXDisposeViewPort(fViewPort);
- fViewPort = kODNULL;
- }
-
- inherited::CleanupPrintingEnv(ev,initiator);
- }
-
- //---------------------------------------------------------------------------------
- // CGXPrinter::EnableMenus
- //---------------------------------------------------------------------------------
-
- void CGXPrinter::EnableMenus( Environment* ev, ODBoolean enable )
- {
- // While printing/page-setup dialogs are up, we need to disable all irrelevant
- // menu commands except the standard Undo/Cut/Copy/Paste/Clear. We also need
- // to fill out an EditMenuRec for GX to tell it where those commands are.
-
- ODWindowState* windowState = fSession->GetWindowState(ev);
- TempODMenuBar mbar = windowState->AcquireCurrentMenuBar(ev);
-
- if (enable)
- {
- // Called after dialog goes away.
- mbar->EnableAll(ev);
- mbar->EnableCommand(ev, kODCommandAbout, kODTrue);
- }
- else
- {
- // Called before dialog comes up.
- mbar->DisableAll(ev);
- mbar->EnableCommand(ev, kODCommandAbout, kODFalse);
-
- ODMenuID menuID;
-
- mbar->GetMenuAndItem(ev, kODCommandUndo, &(fEditMenuRec.editMenuID), &(fEditMenuRec.undoItem));
- mbar->GetMenuAndItem(ev, kODCommandCut, &menuID, &(fEditMenuRec.cutItem));
- mbar->GetMenuAndItem(ev, kODCommandCopy, &menuID, &(fEditMenuRec.copyItem));
- mbar->GetMenuAndItem(ev, kODCommandPaste, &menuID, &(fEditMenuRec.pasteItem));
- mbar->GetMenuAndItem(ev, kODCommandClear, &menuID, &(fEditMenuRec.clearItem));
-
- mbar->EnableCommand(ev, kODCommandEditMenu, kODTrue);
- mbar->EnableCommand(ev, kODCommandRedo, kODFalse);
- mbar->EnableCommand(ev, kODCommandUndo, kODTrue);
- mbar->EnableCommand(ev, kODCommandCut, kODTrue);
- mbar->EnableCommand(ev, kODCommandCopy, kODTrue);
- mbar->EnableCommand(ev, kODCommandPaste, kODTrue);
- mbar->EnableCommand(ev, kODCommandPasteAs, kODFalse);
- mbar->EnableCommand(ev, kODCommandClear, kODTrue);
- mbar->EnableCommand(ev, kODCommandSelectAll, kODFalse);
- mbar->EnableCommand(ev, kODCommandGetPartInfo, kODFalse);
- mbar->EnableCommand(ev, kODCommandPreferences, kODFalse);
- mbar->EnableCommand(ev, kODCommandViewAsWin, kODFalse);
-
- // Replace contents of Undo menu items with standard strings from rsrc:
- CUsingLibraryResources r;
-
- ODIText* menuText = GetODITextInd(rMenuStrID, kPMUndoStrIndex);
- mbar->SetItemString(ev, kODCommandUndo, menuText);
- DisposeIText(menuText);
-
- menuText = GetODITextInd(rMenuStrID, kPMRedoStrIndex);
- mbar->SetItemString(ev, kODCommandRedo, menuText);
- DisposeIText(menuText);
- }
-
- mbar->Display(ev);
- }
-
- //---------------------------------------------------------------------------------
- // CGXPrinter::RunPageSetupDialog
- //---------------------------------------------------------------------------------
-
- ODBoolean CGXPrinter::RunPageSetupDialog( Environment *ev )
- {
- PrintingEventHandler idleHandler(ev, fSession, fJob);
-
- this->EnableMenus(ev,kODFalse);
-
- ODBoolean success = (GXJobDefaultFormatDialog(fJob, &fEditMenuRec) == gxOKSelected);
-
- this->EnableMenus(ev,kODTrue);
-
- THROW_IF_JOB_ERROR(fJob);
-
- return success;
- }
-
- //---------------------------------------------------------------------------------
- // CGXPrinter::RunPrintDialog
- //---------------------------------------------------------------------------------
-
- ODBoolean CGXPrinter::RunPrintDialog(Environment* ev)
- {
- ODBoolean success;
-
- TRY
- // Display the Print dialog.
- PrintingEventHandler idleHandler(ev, fSession, fJob);
-
- this->EnableMenus(ev,kODFalse);
- success = (GXJobPrintDialog(fJob, &fEditMenuRec) == gxOKSelected);
- this->EnableMenus(ev,kODTrue);
-
- THROW_IF_JOB_ERROR(fJob);
- CATCH_ALL
- success = kODFalse;
- ENDTRY
-
- return success;
- }
-
- //---------------------------------------------------------------------------------
- // CGXPrinter::PrintDocument
- //---------------------------------------------------------------------------------
-
- void CGXPrinter::DoPrint(Environment* ev, ODShape* area)
- {
- PrintingEventHandler idleHandler(ev, fSession, fJob);
-
- this->EnableMenus(ev, kODFalse);
-
- // Check to see if the user wanted to print everything, or just
- // selected pages.
- long firstPage, lastPage;
- GXGetJobPageRange(fJob, &firstPage, &lastPage);
-
- ODULong pageCount = this->CountPages(ev, area);
- if ( lastPage > pageCount )
- lastPage = pageCount;
-
- // Print the pages, one at a time.
- for (int page = firstPage; page <= lastPage; page++)
- {
- this->PrintPage(ev, page, area); // SHAZAM!
- }
-
- this->EnableMenus(ev, kODTrue);
- }
-
- //---------------------------------------------------------------------------------
- // CGXPrinter::PrintAShape [static method]
- //---------------------------------------------------------------------------------
-
- OSErr CGXPrinter::PrintAShape(gxShape currentShape, long refCon)
- {
- // This is a static method called by the QD->GX translator. Any QuickDraw
- // command in the facet's QD port will be converted to a GX shape and sent here.
- // We just draw it into the printing viewport so the printer will get it.
-
- CGXPrinter* printer = (CGXPrinter*)refCon;
- gxShapeType shapeType = GXGetShapeType(currentShape);
- ODRect pageRect = printer->GetPageRect(somGetGlobalEnvironment());
-
- if ((shapeType == gxEmptyType) || (shapeType == gxFullType) || (shapeType == gxPictureType)
- || GXTouchesBoundsShape((gxRectangle*)&pageRect, currentShape))
- {
- GXSetShapeViewPorts(currentShape, 1, &printer->fViewPort);
- GXDrawShape(currentShape);
- }
-
- return GXGetGraphicsError(kODNULL);
- }
-
-
- //=================================================================================
- // PrintingEventHandler implementation
- //=================================================================================
-
- Environment* PrintingEventHandler::sEv = kODNULL;
- ODSession* PrintingEventHandler::sSession = kODNULL;
- gxJob PrintingEventHandler::sgxJob = kODNULL;
-
- //---------------------------------------------------------------------------------
- // PrintingEventHandler::PrintingEventHandler
- //---------------------------------------------------------------------------------
-
- PrintingEventHandler::PrintingEventHandler(Environment* ev, ODSession* session, gxJob job)
- {
- sEv = ev;
- sSession = session;
- sgxJob = job;
-
- fgxJob = job;
- fPrintingEventOverrideProcPtr = NewGXPrintingEventProc(PrintingEventHandler::PrintingEventOverride);
-
- GXInstallApplicationOverride(fgxJob, gxPrintingEventMsg, fPrintingEventOverrideProcPtr);
- }
-
- //---------------------------------------------------------------------------------
- // PrintingEventHandler::~PrintingEventHandler
- //---------------------------------------------------------------------------------
-
- PrintingEventHandler::~PrintingEventHandler()
- {
- GXInstallApplicationOverride(fgxJob, gxPrintingEventMsg, kODNULL);
-
- DisposeRoutineDescriptor(fPrintingEventOverrideProcPtr);
-
- sEv = kODNULL;
- sSession = kODNULL;
- }
-
- //---------------------------------------------------------------------------------
- // PrintingEventHandler::PrintingEventOverride
- //---------------------------------------------------------------------------------
-
- OSErr PrintingEventHandler::PrintingEventOverride(EventRecord* anEvent, Boolean filterEvent)
- {
- // this is a static method used as a callback by GX...
-
- WASSERT(sSession != kODNULL);
- WASSERT(sEv != kODNULL);
-
- //WARN("Within SBPrintingEventHandler::SBPrintingEventOverride");
-
- if (!filterEvent)
- {
- switch(anEvent->what)
- {
- case nullEvent:
- case mouseDown:
- case keyDown:
- case autoKey:
- break;
-
- case osEvt:
- // Update the job on a resume event in case user changed printer in Finder:
- if( ((anEvent->message>>24) & 0x00FF)==0x01 && (anEvent->message & 0x01) ) {
- GXUpdateJob(sgxJob);
- }
- // continue to default case:
-
- default:
- TRY{
- ODDispatcher* dispatcher = sSession->GetDispatcher(sEv);
- if (dispatcher)
- dispatcher->Dispatch(sEv, (ODEventData*)anEvent);
- }CATCH_ALL{
- WARN("Error dispatching event");
- }ENDTRY
- break;
- }
- }
-
- return noErr;
- }
-